function Gameboard() {

    this.score = 0;
    this.lines = 0;
    this.level = 0;
    this.speed = 0;
    this.bigPipe = 0;
    this.bigCycle = 0;
    this.pipeTotal = 0;
    this.cycleTotal = 0;
    this.pipeLength = 0;
    this.transP = 0;

    this.juice = -1;

    this.pipeIdentification = null;
    this.cycleIdentification = null;

    this.cCount = 0;

    this.dScale;

    this.piping = false;
    this.moving = false;
    this.destroying = false;

    this.board = new Array();

    for( var i = 0; (i < 12); i++) {
      this.board[i] = new Array();
      for( var j = 0; (j < 23); j++) {
        this.board[i][j] = null;
      }
    }

    // block arrays
    this.pipeQ = new Array();
    this.changeQ = new Array();
    this.cycleQ = new Array();
    this.cycleBackQ = new Array();

    this.cycleMulti = new Array();
    this.cycleCount = new Array();
    this.cycleStat = new Array(); 

    this.pipeCount = new Array();
    this.pipeStat = new Array();
}

Gameboard.prototype.checkLines = function() {

  var m = 0;
  var n = 22;

  this.pipeIdentification = 0;
  this.cycleIdentification = 0;

  while (n > -1) {

    var lineCheck = false;

    if (n == 1) {
      // check for game over
      this.board.each(function(column) {
        if (column[1] != null) { return true; }
      });
    }

    // scan - row cols
    this.board.each(function (col) {
      if(col[n] == null) { lineCheck = true; }
    });

    if (lineCheck == false) {
      this.score += 2;
      this.lines++;
      
      if ((this.lines % 10) == 0) {
        this.level++;
// TODO - increase speed
      }
      if (this.lines == 200) {
        this.juice = 510;
      }
      this.getFirstPipes(n);
    }
    m = 0;
    n--;
  }
  return false;
}

Gameboard.prototype.getFirstPipes = function(line) {
  var semiScore = 0;

  this.cycleCount.clear();
  this.cycleMulti.clear();

  for( var i = 0; (i < 12); i++) {

    this.board[i][line].trans = 100;
    this.board[i][line].destroying = true;

    // if - up connect
    if (this.board[i][line].trueConnections[0] == true) {
      if ((this.board[i][line].pipeId == -1) && (this.board[i][(line - 1)].pipeId == -1)) {

        // if neither Block is ID'd yet
        this.board[i][line].setPiping(this.pipeIdentification);
        this.board[i][line - 1].setPiping(this.pipeIdentification);

        this.pipeQ.push(this.board[i][line]);
        this.pipeQ.push(this.board[i][(line - 1)]);

        this.setPLinks(this.board[i][line], 0);
        
        this.pipeCount.push(2);
        this.pipeIdentification++;
      }       
      else if (this.board[i][line].pipeId == -1) {
        this.pipeCount[this.board[i][line - 1].pipeId]++;
        this.board[i][line].setPiping(this.board[i][line - 1].pipeid);

        this.pipeQ.push(this.board[i][line]);
        this.setPLinks(this.board[i][line], 0);
      }
      else if (this.board[i][line - 1].pipeId == -1) {
        this.pipeCount[this.board[i][line].pipeId]++;
        this.board[i][line - 1].setPiping(this.board[i][line].pipeId);

        this.pipeQ.push(this.board[i][line - 1]);
        this.setPLinks(this.board[i][line], 0);
      }
    } // if - up connect

    // if - right connect
    if (this.board[i][line].trueConnections[1] == true) {

      if ((this.board[i][line].pipeId == -1) && (this.board[(i + 1)][line].pipeId == -1)) {

        // if neither Block yet ID'd
        this.board[i][line].setPiping(this.pipeIdentification);
        this.board[i + 1][line].setPiping(this.pipeIdentification);

        this.pipeQ.push(this.board[i][line]);
        this.pipeQ.push(this.board[i + 1][line]);
        this.setPLinks(this.board[i][line], 1);

        this.pipeCount.push(2);
        this.pipeIdentification++;
      }     
      else if (this.board[i][line].pipeId == -1) {
        this.pipeCount[this.board[(i + 1)][line].pipeId] += 1;
        this.board[i][line].setPiping(this.board[i + 1][line].pipeId);

        this.pipeQ.push(this.board[i][line]);
        this.setPLinks(this.board[i][line], 1);
      }
      else if (this.board[i + 1][line].pipeId == -1) {
        this.pipeCount[this.board[i][line].pipeId]++;
        this.board[i + 1][line].setPiping(this.board[i][line].pipeId);

        this.pipeQ.push(this.board[i + 1][line]);
        this.setPLinks(this.board[i][line], 1);
      }
    } // if - right connect

    // if - down connect
    if (this.board[i][line].trueConnections[2] == true) {

      if ((this.board[i][line].pipeId == -1) && (this.board[i][line + 1].pipeId == -1)) {

        // if neither Block yet ID'd
        this.board[i][line].setPiping(this.pipeIdentification);
        this.board[i][line + 1].setPiping(this.pipeIdentification)

        this.pipeQ.push(this.board[i][line]);
        this.pipeQ.push(this.board[i][(line + 1)]);
                
        this.setPLinks(this.board[i][line], 2);

        this.pipeCount.push(2);
        this.pipeIdentification++;
      }
      else if (this.board[i][line].pipeId == -1) {
        this.pipeCount[this.board[i][line + 1].pipeId]++;
        this.board[i][line].setPiping(this.board[i][line + 1].pipeId);

        this.pipeQ.push(this.board[i][line]);
        this.setPLinks(this.board[i][line], 2);
      }
      else if (this.board[i][(line + 1)].pipeId == -1) {
        this.pipeCount[this.board[i][line].pipeId]++;
        this.board[i][line + 1].setPiping(this.board[i][line].pipeId);

        this.pipeQ.push(this.board[i][(line + 1)]);
        this.setPLinks(this.board[i][line], 2);
      }
    } // if - down connect

    // if - left connect
    if (this.board[i][line].trueConnections[3] == true) {

      if ((this.board[i][line].pipeId == -1) && (this.board[i - 1][line].pipeId == -1)) {

        // if neither Block yet ID'd
        this.board[i][line].setPiping(this.pipeIdentification);
        this.board[i - 1][line].setPiping(this.pipeIdentification);

        this.board[i][line].pipeId = this.pipeIdentification;
        this.board[i][line].piping = true;
        
        this.pipeQ.push(this.board[i][line]);
        this.pipeQ.push(this.board[(i - 1)][line]);

        this.setPLinks(this.board[i][line], 3);

        this.pipeCount.push(2);
        this.pipeIdentification++;
      }
      else if (this.board[i][line].pipeId == -1) {
        
        this.pipeCount[this.board[i - 1][line].pipeId]++;
        this.board[i][line].setPiping(this.board[i - 1][line].pipeId);
       
        this.pipeQ.push(this.board[i][line]);
        this.setPLinks(this.board[i][line], 3);
      }
      else if (this.board[(i - 1)][line].pipeId == -1) {
        
        this.pipeCount[this.board[i][line].pipeId]++;
        this.board[i - 1][line].setPiping(this.board[i][line].pipeId);

        this.pipeQ.push(this.board[i - 1][line]);
        this.setPLinks(this.board[i][line], 3);
      }
    } // if - left connect
  }  // for - all blocks in line get pipeChecked

//  window.alert('pipeQ.size(): ' + this.pipeQ.size());

  if (this.pipeQ.size() > 0) {
//    window.alert('setting piping! ');
    this.piping = true;
  }
}

Gameboard.prototype.makePipes = function() {
  // create pipes for each Block ref in pipeQ
  var cycleCheck  = false;

  var size = this.pipeQ.size();
  var temp = 0, xPos = 0, yPos = 0; 
  var currentBlock = null;
  
  while (size > 0) {

    currentBlock = this.pipeQ.pop();
    
    xPos    = currentBlock.xPosition;
    yPos    = currentBlock.yPosition;

    cycleCheck  = false;
    currentBlock.piping = true;
    
    // if - pipe connect up
    if (currentBlock.trueConnections[0] == true) {
      if (this.board[xPos][yPos - 1].piping == false) {
        this.board[xPos][yPos - 1].setPiping(this.board[xPos][yPos].pipeId); 

        this.setPLinks(this.board[xPos][yPos], 0);
        this.pipeCount[this.board[xPos][yPos].pipeId] +=  1;
  
        this.pipeQ.unshift(this.board[xPos][yPos - 1]);
        this.pipeLength++;
      }
      else if ((this.board[xPos][yPos - 1].piping == true) && (this.board[xPos][yPos - 1].found[2] == false)) {
        if (this.board[xPos][yPos - 1].pipeId == this.board[xPos][yPos].pipeId)  {
          if (this.board[xPos][yPos].cycling == false) {
            this.setPLinks(this.board[xPos][yPos], 0);
            cycleCheck  = false;
          }
        }
        else  {
          if (this.board[xPos][yPos - 1].pipeId < this.board[xPos][yPos].pipeId) {
            this.pipeCount[this.board[xPos][yPos - 1].pipeId] += this.pipeCount[this.board[xPos][yPos].pipeId];
            this.pipeCount[this.board[xPos][yPos].pipeId] = -1;
            
            this.changePipeId( this.board[xPos][yPos], this.board[xPos][yPos].pipeId, this.board[xPos][yPos - 1].pipeId);
            this.setPLinks(this.board[xPos][yPos], 0);          
          }
          else if (this.board[xPos][yPos - 1].pipeId > this.board[xPos][yPos].pipeId) {
            this.pipeCount[this.board[xPos][yPos].pipeId] += this.pipeCount[this.board[xPos][yPos - 1].pipeId];
            this.pipeCount[this.board[xPos][yPos - 1].pipeId] = -1;

            this.changePipeId( this.board[xPos][yPos - 1], this.board[xPos][yPos - 1].pipeId, this.board[xPos][yPos].pipeId);
            this.setPLinks(this.board[xPos][yPos], 0);
          }
        }
      }
    } // if - pipe connect up

    // if -  pipe connect right
    if (currentBlock.trueConnections[1] == true) {
      if (this.board[(xPos + 1)][yPos].piping == false) {
        this.board[xPos + 1][yPos].setPiping(this.board[xPos][yPos].pipeId);
       
        this.setPLinks(this.board[xPos][yPos], 1);
        this.pipeCount[this.board[xPos][yPos].pipeId] += 1;
        
        this.pipeQ.unshift(this.board[xPos + 1][yPos]);
        this.pipeLength++;
      }
      else if ((this.board[xPos + 1][yPos].piping == true) && (this.board[xPos + 1][yPos].found[3] == false)) {
        if (this.board[xPos + 1][yPos].pipeId == this.board[xPos][yPos].pipeId) {
          if (this.board[xPos][yPos].cycling == false) {                    
            this.setPLinks(this.board[xPos][yPos], 1);
            cycleCheck  = true;
          }
        }
        else {
          if (this.board[xPos + 1][yPos].pipeId < this.board[xPos][yPos].pipeId) {
            this.pipeCount[this.board[xPos + 1][yPos].pipeId] += this.pipeCount[this.board[xPos][yPos].pipeId];
            this.pipeCount[this.board[xPos][yPos].pipeId] = -1;
            
            this.changePipeId( this.board[xPos][yPos], this.board[xPos][yPos].pipeId, this.board[xPos + 1][yPos].pipeId);
            this.setPLinks(this.board[xPos][yPos], 1);
          }
          else if (this.board[xPos + 1][yPos].pipeId > this.board[xPos][yPos].pipeId) {
            this.pipeCount[this.board[xPos][yPos].pipeId] += this.pipeCount[this.board[xPos + 1][yPos].pipeId];
            this.pipeCount[this.board[xPos + 1][yPos].pipeId] = -1;
            
            this.changePipeId(this.board[xPos + 1][yPos], this.board[xPos + 1][yPos].pipeId, this.board[xPos][yPos].pipeId);
            this.setPLinks(this.board[xPos][yPos],  1);
          }
        }
      }
    } // if -  pipe connect right

    // if - pipe connect down
    if (currentBlock.trueConnections[2] == true) {
      if (this.board[xPos][yPos + 1].piping == false) {
        this.board[xPos][yPos + 1].setPiping(this.board[xPos][yPos].pipeId);

        this.setPLinks(this.board[xPos][yPos], 2);
        this.pipeCount[this.board[xPos][yPos].pipeId] += 1;

        this.pipeQ.unshift(this.board[xPos][(yPos + 1)]);
        this.pipeLength++;
      }
      else if ((this.board[xPos][yPos + 1].piping == true) && (this.board[xPos][yPos + 1].found[0] == false)) {
        if (this.board[xPos][yPos + 1].pipeId == this.board[xPos][yPos].pipeId) {
          if (this.board[xPos][yPos].cycling == false) {
            this.setPLinks(this.board[xPos][yPos], 2);
            cycleCheck = false;
          }
        }
        else  {
          if (this.board[xPos][yPos + 1].pipeId < this.board[xPos][yPos].pipeId) {
            this.pipeCount[this.board[xPos][yPos + 1].pipeId] += this.pipeCount[this.board[xPos][yPos].pipeId];
            this.pipeCount[this.board[xPos][yPos].pipeId] = -1;

            this.changePipeId( this.board[xPos][yPos], this.board[xPos][yPos].pipeId, this.board[xPos][yPos + 1].pipeId);
            this.setPLinks(this.board[xPos][yPos], 2);
          }
          else if (this.board[xPos][yPos + 1].pipeId > this.board[xPos][yPos].pipeId) {
            this.pipeCount[this.board[xPos][yPos].pipeId] += this.pipeCount[this.board[xPos][yPos + 1].pipeId];
            this.pipeCount[this.board[xPos][yPos + 1].pipeId] = -1;

            this.changePipeId(this.board[xPos][yPos + 1], this.board[xPos][yPos + 1].pipeId, this.board[xPos][yPos].pipeId);
            this.setPLinks(this.board[xPos][yPos], 2);
          }
        }
      }
    } // if - pipe connect down

    // if - pipe connect left
    if (currentBlock.trueConnections[3] == true) {
      if (this.board[(xPos - 1)][yPos].piping == false) {
        this.board[xPos - 1][yPos].setPiping(this.board[xPos][yPos].pipeId);

        this.pipeCount[this.board[xPos][yPos].pipeId] += 1;
        this.setPLinks(this.board[xPos][yPos], 3);

        this.pipeQ.unshift(this.board[xPos - 1][yPos]);
        this.pipeLength++;
      }
      else if ((this.board[xPos - 1][yPos].piping == true) && (this.board[xPos - 1][yPos].found[1] == false)) {
        if (this.board[xPos - 1][yPos].pipeId == this.board[xPos][yPos].pipeId) {
          if (this.board[xPos][yPos].cycling == false) {
            this.setPLinks(this.board[xPos][yPos], 3);
            cycleCheck = true;   
          }
        }
        else  {
          if (this.board[xPos - 1][yPos].pipeId < this.board[xPos][yPos].pipeId) {
            this.pipeCount[this.board[xPos - 1][yPos].pipeId] += this.pipeCount[this.board[xPos][yPos].pipeId];
            this.pipeCount[this.board[xPos][yPos].pipeId] = -1;

            this.changePipeId( this.board[xPos][yPos], this.board[xPos][yPos].pipeId, this.board[xPos - 1][yPos].pipeId);
            this.setPLinks(this.board[xPos][yPos], 3);
          }
          else if (this.board[xPos - 1][yPos].pipeId < this.board[xPos][yPos].pipeId) {
            this.pipeCount[this.board[xPos][yPos].pipeId] += this.pipeCount[this.board[xPos - 1][yPos].pipeId];
            this.pipeCount[this.board[xPos - 1][yPos].pipeId] = -1;

            this.changePipeId(this.board[xPos - 1][yPos], this.board[xPos - 1][yPos].pipeId, this.board[xPos][yPos].pipeId);
            this.setPLinks(this.board[xPos][yPos], 3);
          }
        }
      }
    } // if - pipe connnect left

    if ((cycleCheck == true) && (currentBlock.cycling == false)) {
      temp  = this.makeCycle(currentBlock);
          
      var count = 0;
      var sum = 0;

      while (count < this.cycleCount.size()) {
        for(var i = 0; (i < 12); i++) {
          for(var j = 0; (j < 24); j++) {
            if (this.board[i][j] != null) {
              if (this.board[i][j].cycleId == count) {
                sum += 1;
              }
            }
          }
        }

        if (this.cycleCount[count] != -1) {
          this.cycleCount[count] = sum;
        }
        sum   = 0;
        count++;
      }
    }
    size--;
  }

//  window.alert('pipeQ.size from makePipes(): ' + this.pipeQ.size());

  // if no pipes remain to be explored
  if (this.pipeQ.size() == 0) {
    
    // need to fin pipe sizes here

    this.piping = false;
    this.destroy(false);
    this.destroying = true;
    this.moving = false;
    return(false);
  }
  else {
    // still piping
    this.piping  = true;
    return(true);
  }

}

Gameboard.prototype.setPLinks = function(block, thisLink) {
  
  var xPos = block.xPosition;
  var yPos = block.yPosition;

  block.found[thisLink]  = true;

  switch(thisLink) {
    case 0: // up
      this.board[xPos][yPos].links[thisLink] = this.board[xPos][(yPos - 1)];
      this.board[xPos][(yPos - 1)].links[2] = this.board[xPos][yPos];
      this.board[xPos][(yPos - 1)].found[2] = true;
      break;
    case 1: // right
      this.board[xPos][yPos].links[thisLink] = this.board[(xPos + 1)][yPos];
      this.board[(xPos + 1)][yPos].links[3] = this.board[xPos][yPos];
      this.board[(xPos + 1)][yPos].found[3] = true;
      break;
    case 2: // down
      this.board[xPos][yPos].links[thisLink] = this.board[xPos][(yPos + 1)];
      this.board[xPos][(yPos + 1)].links[0] = this.board[xPos][yPos];
      this.board[xPos][(yPos + 1)].found[0] = true;
      break;
    case 3: // left
      this.board[xPos][yPos].links[thisLink] = this.board[(xPos - 1)][yPos];
      this.board[(xPos - 1)][yPos].links[1]  = this.board[xPos][yPos];
      this.board[(xPos - 1)][yPos].found[1] = true;
      break;
  }
}

Gameboard.prototype.destroy = function(finalize) {

  try {
    if (finalize) {
      for( var i = 0; (i < 12); i++) {
        for( var j = 0; (j < 23); j++) {
          if ((this.board[i][j] != null) && (this.board[i][j].destroying === true)) {
            $('game_board').removeChild(this.board[i][j].div);
            var tmp = this.board[i][j];
            this.board[i][j] = null;
            delete tmp;
          }
        }
      }

  //    $('test_div').innerHTML = dumpObj(this.board, 'b', ';', 2);
    }
    else {
      for( var i = 0; (i < 12); i++) {
        for( var j = 0; (j < 23); j++) {

          if ((this.board[i][j] != null) && (this.board[i][j].piping || this.board[i][j].destroying)) {
            
            // destroy all piece associations with other Blocks
            if (this.board[i][j].pieceAssociations[0] == true) {
              this.board[i][j - 1].pieceAssociations[2] = false;
            } // if assoc up

            if (this.board[i][j].pieceAssociations[1] == true) {
              this.board[i + 1][j].pieceAssociations[3] = false;
            }   // if assoc right
    
            if (this.board[i][j].pieceAssociations[2] == true) {
              this.board[i][j + 1].pieceAssociations[0] = false;
            }   // if assoc down

            if (this.board[i][j].pieceAssociations[3] == true) {
              this.board[i - 1][j].pieceAssociations[1] = false;
            } // if assoc left

            this.board[i][j].destroying = true;
//            this.board[i][j].div.style.border = '2px solid black';

          } // if Block exists and is being destroyed - destroy
        }
      }
    }
  }
  catch(e) {
    window.alert(e);
  }
}

Gameboard.prototype.moveDown = function() {
  
  var allSet = false, dropThisBlock = false;
  var associations = new Array(null, null, null, null);

  try {
    for (var j = 21; (j > 0); j--) {
      for (var i = 0; (i < 12); i++) {

        if ((this.board[i][j] != null) && (this.board[i][(j + 1)] == null)) {
    
  //        debug('found: [' + i + '][' + j + ']');  
   
          for( var k = 0; (k < 4); k++) {
            associations[k] = null;
          } 

          this.board[i][j].droppable = true;
//          this.board[i][j].div.style.borderBottom = '3px solid red';
          
          // seed findBlocks with current Block
          associations[0] = this.board[i][j];

          // find all blocks currently in gameBoard that are related to current Block
          this.findBlocks(associations, 0, 0, true);

          dropThisBlock = true;

          var z = 0;
          while ((z < 4) && (associations[z] != null) && (dropThisBlock == true)) {
            if (associations[z].droppable == false) {
              dropThisBlock = false;
            }
            if (associations[z].yPosition == 22) {
              associations[z].droppable = false;
              dropThisBlock = false;
            }
            z++;
          }

          // reset association array position
          z = 0;
          if (dropThisBlock == true) {
            while (z < 4) {
              if (associations[z] != null) {  
                associations[z].droppable = false;
                associations[z].yPosition++;
                associations[z].setPosition();

//                associations[z].div.style.borderBottom = '3px solid blue';
     
                this.board[associations[z].xPosition][associations[z].yPosition] = associations[z];
                this.board[associations[z].xPosition][(associations[z].yPosition - 1)] = null;
              }
              z++;
            }
          }
        }
        else if (this.board[i][j] != null) {
          this.board[i][j].droppable  = false;
        }
      }
    }

    var y = 22;
    dropThisBlock = false;

    // check whether there still remain Blocks in gameBoard that can moveDown
    while ((y > 0) && (dropThisBlock == false)) {
      var x = 0;
      while ((x < 12) && (dropThisBlock == false)) {
        if ((this.board[x][y] != null) && (this.board[x][(y + 1)] == null)) {

          for( var k = 0; (k < 4); k++) {
            associations[k] = null;
          } 

          this.board[x][y].droppable = true;

          // seed findBlocks with current Block
          associations[0] = this.board[x][y];

          // find all blocks currently in gameBoard that are related to current C_Block
          this.findBlocks( associations, 0, 0, true);

          dropThisBlock = true;

          var z = 0;
          while ((z < 4) && (associations[z] != null) && (dropThisBlock == true)) {
            if (associations[z].droppable == false) {
              dropThisBlock = false;
            }

            if (associations[z].yPosition == 22) {
              associations[z].droppable = false;
              dropThisBlock = false;
            }
            z++;
          }
        }
        x++;
      }
      y--;
    }

    if (dropThisBlock == false) {
      for (var i = 0; (i < 12); i++) {
        for (var j = 23; (j > 0); j--) {
          if (this.board[i][j] != null) {
            this.board[i][j].droppable  = false;
            this.setPipeConnections(this.board[i][j]);
          }
        }
      }
      allSet = true;
      this.moving = false;
      this.pipeCount.clear();
      this.checkLines();
    }
    else {
//      window.alert('still got shit not droppin');
    }
  }
  catch(ex) {
    window.alert(ex);
  }

  return(allSet);
}

Gameboard.prototype.findBlocks = function(startBlock, index, current, dropThisBlock) {

  var tempBlock = null;

  // up
  if (startBlock[index].pieceAssociations[0] == true) {
//    startBlock[index].div.style.borderTop = '3px solid green';
 
    tempBlock = this.board[startBlock[index].xPosition][(startBlock[index].yPosition - 1)];
    tempBlock.droppable = true;
    if (!this.alreadyAssociated(startBlock, tempBlock)) {
      startBlock[++current] = tempBlock;
    }
  }

  // right
  if (startBlock[index].pieceAssociations[1] == true) {
//    startBlock[index].div.style.borderRight = '3px solid green';
 
    tempBlock = this.board[(startBlock[index].xPosition + 1)][startBlock[index].yPosition];
    if (!this.alreadyAssociated(startBlock, tempBlock)) {
      startBlock[++current] = tempBlock;
    }
  }

  // down
  if (startBlock[index].pieceAssociations[2] == true) {
//    startBlock[index].div.style.borderBottom = '3px solid green';
 
    tempBlock = this.board[startBlock[index].xPosition][(startBlock[index].yPosition + 1)];
    if (!this.alreadyAssociated(startBlock, tempBlock)) {
      startBlock[++current] = tempBlock;
    }
  }

  // left
  if (startBlock[index].pieceAssociations[3] == true) {
//    startBlock[index].div.style.borderLeft = '3px solid green';
 
    tempBlock = this.board[(startBlock[index].xPosition - 1)][startBlock[index].yPosition];
    if (!this.alreadyAssociated(startBlock, tempBlock)) {
      startBlock[++current] = tempBlock;
    }
  }

  if (current < 4) {
    if (current > index) {
      // hack to prevent error
      if (startBlock[index]) {
        this.findBlocks(startBlock, ++index, current, startBlock[index].droppable);
      }
    }
  }

	this.sortStartBlock(startBlock, (current + 1));
}

Gameboard.prototype.alreadyAssociated = function(startBlock, checkBlock) {
  for(var i = 0; ((i < 4) && (startBlock[i] != null)); i++) {
    if (checkBlock == startBlock[i]) {
      return true;
    }
  }
  return false;
}

Gameboard.prototype.sortStartBlock = function(startBlock, size) {
  
  var i = 0, j = 0;
  
  while ((i < (size - 1)) && (startBlock[i] != null)) {
    j =  (i + 1);
    while ((j < size) && (startBlock[j] != null)) {
      if (startBlock[j].yPosition > startBlock[i].yPosition) {
        var block = startBlock[i];
        startBlock[i] = startBlock[j];
        startBlock[j] = block;
      }
      j++;
    }
    i++;
  }
}


Gameboard.prototype.changeCycleId = function(cycleId, newId) {
  for(var i = 0; (i < 12); i++) {
    for(var j = 0; (j < 24); j++) {
      if (this.board[i][j] != null) {    
        if (this.board[i][j].cycleId == cycleId) {
          this.board[i][j].cycleId = newId;
        }
      }
    }
  }
}

Gameboard.prototype.cycleClean = function() {

  var cycleCheck = false;
  var idCheck = false;
  
  var count = 0;
  var id = 0;

  var ids = new Array();
  var addrs = new Array();
  var addBlocks = new Array();

  for(var i = 0; (i < 12); i++) {
    for(var j = 0; (j < 24); j++) {
      for(var n = 0; (n < 4); n++) {

        if(this.board[i][j] != null) {
          if(this.board[i][j].piping == true) {
            if(this.board[i][j].links[n] != null) {
              if(this.board[i][j].links[n].cycleId != -1) {
                
                ids.push(this.board[i][j].links[n].cycleId);
                addrs.push(this.board[i][j].links[n]);
                count = n;
                while(count < ids.size()) {
                
                  if (this.board[i][j].links[count] != null) {
                    if (this.board[i][j].links[n] != addrs[count]) {
                      if (this.board[i][j].links[n].cycleId == ids[count]) {
                        idCheck = true;
                        id = this.board[i][j].links[count].cycleId;
                      break;
                      }
                    }
                  }
                  count++;
                }

                if (idCheck == true) {
                
                  this.board[i][j].cycleId = id;
                  this.board[i][j].cycling = true;
                  for (var z = 0;(z < 4); z++) {
                    if (this.board[i][j].links[z] != null) {
                      if (this.board[i][j].links[z].cycling == false) {
                        addBlocks.push(this.board[i][j].links[z]);
                      }
                    }
                  }
                }
                idCheck = false;
              }
            }
          }
        }
      }
     
      ids.clear(); 
      addrs.clear();

      while (addBlocks.size() != 0) {
        var block = addBlocks.pop();

        count = 0;
        for (var n = 0; (n < 4); n++) {

          if (block.links[n] != null) {
            if (block.links[n].cycling == true) {
              ids.push(this.board[i][j].links[n].cycleId);
              addrs.push(this.board[i][j].links[n]);
              count = n;
              while(count < ids.size()) {
                
                if (this.board[i][j].links[count] != null) {
                  if (this.board[i][j].links[n] != addrs[count]) {
                    if (this.board[i][j].links[n].cycleId == ids[count]) {
                      idCheck = true;
                      id = this.board[i][j].links[count].cycleId;
                      break;
                    }
                  }
                }
                count++;
              }
              if (idCheck == true) {

                this.board[i][j].cycleID = id;
                this.board[i][j].cycling = true;
                for (var z = 0; (z < 4); z++) {
                  if (this.board[i][j].links[z] != null) {
                    if (this.board[i][j].links[z].cycling == false) {
                      addBlocks.unshift(this.board[i][j].links[z]);
                    }
                  }
                }
              }
            }
            else {
              addBlocks.unshift(block.links[n]);
            }
          }
        }
      }
      ids.clear();
      addrs.clear();
    }
  }
}

Gameboard.prototype.changeBlocks = function() {
  var links = 0;
    
  for(var i = 0; (i < 12); i++) {
    for(var j = 0; (j < 23); j++) {
      if (this.board[i][j] != null) {
        if (this.board[i][j].cycling == true) {

          links = 0;

          this.board[i][j].trueConnections.each(function(tc) { tc = true; }); 

          if (links == 3) {
            this.board[i][j].blockType = 2;
            if (this.board[i][j].trueConnections[0] == false) {
              this.board[i][j].rotation = 2;
            }
            else if (this.board[i][j].trueConnections[1] == false) {
              this.board[i][j].rotation = 3;
            }
            else if (this.board[i][j].trueConnections[2] == false) {
              this.board[i][j].rotation = 0;
            }
            else if (this.board[i][j].trueConnections[3] == false) {
              this.board[i][j].rotation = 1;
            }
          }
          else if (links == 2) {
            if (this.board[i][j].trueConnections[0] == false) {
              
              if (this.board[i][j].trueConnections[1] == false) {
                this.board[i][j].blockType = 3;
                this.board[i][j].rotation = 2;
              }
              else if (this.board[i][j].trueConnections[2] == false) {
                this.board[i][j].blockType = 1;
                this.board[i][j].rotation = 1;
              }
              else if (this.board[i][j].trueConnections[3] == false) {
                this.board[i][j].blockType = 3;
                this.board[i][j].rotation = 1;
              }
            }
            else if (this.board[i][j].trueConnections[1] == false) {
              if (this.board[i][j].trueConnections[2] == false) {
                this.board[i][j].blockType = 3;
                this.board[i][j].rotation = 3;
              }
              else if (this.board[i][j].trueConnections[3] == false) {
                this.board[i][j].blockType = 1;
                this.board[i][j].rotation = 0;
              }
            }
            else if (this.board[i][j].trueConnections[2] == false) {
              if (this.board[i][j].trueConnections[3] == false) {
                this.board[i][j].blockType  = 3;
                this.board[i][j].rotation = 0;
              }
            }
          }
        }
      }
    }
  }
}

Gameboard.prototype.setPipeConnections = function(setBlock) {

  var xNew = setBlock.xPosition;
  var yNew = setBlock.yPosition;

  //  Check clockwise from top around pipe connections in gameBoard
  //  set trueConnections to true, denoting a connection between two pieces

  if (yNew > 0) {
    if (this.board[xNew][(yNew - 1)] != null) {
      if ((this.board[xNew][yNew].pipeConnections[0] == true) && (this.board[xNew][(yNew - 1)].pipeConnections[2] == true)) {
        this.board[xNew][yNew].trueConnections[0] = true;
        this.board[xNew][(yNew - 1)].trueConnections[2] = true;
      }
      else {
        this.board[xNew][yNew].trueConnections[0] = false;
        this.board[xNew][(yNew - 1)].trueConnections[2] = false;
      }
    }
    else {
      this.board[xNew][yNew].trueConnections[0] = false;
    }
  }
  else {
    this.board[xNew][yNew].trueConnections[0] = false;
  }

  if (xNew < 11) {
    if (this.board[(xNew + 1)][yNew] != null) {
      if ((this.board[xNew][yNew].pipeConnections[1] == true) && (this.board[(xNew + 1)][yNew].pipeConnections[3] == true)) {
        this.board[xNew][yNew].trueConnections[1] = true;
        this.board[(xNew + 1)][yNew].trueConnections[3] = true;
      }
      else {
        this.board[xNew][yNew].trueConnections[1] = false;
        this.board[(xNew + 1)][yNew].trueConnections[3] = false;
      }
    }
    else {
      this.board[xNew][yNew].trueConnections[1] = false;
    }
  }
  else {
    this.board[xNew][yNew].trueConnections[1] = false;
  }

  if (yNew < 23) {
    if (this.board[xNew][yNew + 1] != null) {
      if ((this.board[xNew][yNew].pipeConnections[2] == true) && (this.board[xNew][(yNew + 1)].pipeConnections[0] == true)) {
        this.board[xNew][yNew].trueConnections[2] = true;
        this.board[xNew][(yNew + 1)].trueConnections[0] = true;
      }
      else {
        this.board[xNew][yNew].trueConnections[2] = false;
        this.board[xNew][(yNew + 1)].trueConnections[0] = false;
      }
    }
    else {
      this.board[xNew][yNew].trueConnections[2] = false;
    }
  }
  else {
    this.board[xNew][yNew].trueConnections[2] = false;
  }

  if (xNew > 0) {
    if (this.board[(xNew - 1)][yNew] != null) {
      if ((this.board[xNew][yNew].trueConnections[3] == true) && (this.board[(xNew - 1)][yNew].trueConnections[1] == true)) {
        this.board[xNew][yNew].trueConnections[3] = true;
        this.board[(xNew - 1)][yNew].trueConnections[1] = true;
      }
      else {
        this.board[xNew][yNew].trueConnections[3] = false;
        this.board[(xNew - 1)][yNew].trueConnections[1] = false;
      }
    }
    else {
      this.board[xNew][yNew].trueConnections[3] = false;
    }
  }
  else {
    this.board[xNew][yNew].trueConnections[3] = false;
  }
}

Gameboard.prototype.changePipeId = function(startBlock, oldId, newId) {
  
  this.changeQ.unshift(startBlock);

  // change all pipeIds new Id for blocks in other pipe and rearrange for cycle detection matters

  while(this.changeQ.size() != 0) {
    
    var block = this.changeQ.last();
    block.pipeId= newId;
    this.changeQ.pop();

    if ((block.links[0] != null) && (block.links[0].pipeId != newId)) {
      this.changeQ.unshift(block.links[0]);
    }

    if ((block.links[1] != null) && (block.links[1].pipeId != newId)) {
      this.changeQ.unshift(block.links[1]);
    }
    
    if ((block.links[2] != null) && (block.links[2].pipeId != newId)) {
      this.changeQ.unshift(block.links[2]);
    }

    if ((block.links[3] != null) && (block.links[3].pipeId != newId)) {
      this.changeQ.unshift(block.links[3]);
    } //  if  
  }
}

Gameboard.prototype.makeCycle = function(startBlock) {
  
  var check = false;

  var cId = this.cycleIdentification;
  var cycleCount = 1;
  var time = 0;

  var block = startBlock
  var cycle = null;

  this.cycleMulti.push(false);
  this.cycleCount.push(0);

  this.changeQ.clear(); 
  
  startBlock.cycling = true;
  this.cycleQ.push(startBlock);

  while (this.cycleQ.size() != 0) {

    cycle = this.cycleQ.pop();
    this.changeQ.push(cycle);

    check = false;

    if (cycle.testCycle == true) { continue; }

    cycle.testCycle = true;
    cycle.cycleID = cId;
    
    if ((cycle.links[0] != null) && (cycle.links[0] != cycle.cyp)) {
    
      if (cycle.links[0].testCycle == false) {
        cycle.links[0].p_cyp = cycle;
        this.cycleQ.unshift(cycle.links[0]);
      }
      else if (cycle.links[0].testCycle == true) {
        
        if (cycle.links[0].cycling == false) {
          if (cycle.links[0].cycleId == cId) {
            cycleCount += this.cycleBack(cycle.links[0]);
            this.cycleCount[cID] += cycleCount;
            cycleCount += this.cycleBack(cycle);
            this.cycleCount[cID] += cycleCount; 
          }
        }
        else if ((cycle.links[0].cycleId != cId) && (cycle.links[0].cycleId != -1)) {
          cycleCount += this.cycleBack(cycle);
          if (cycle.links[0].cycleId < cId) {
            this.cycleCount[cycle.links[0].cycleId] += (cycleCount - 1);
            this.cycleMulti[cycle.links[0].cycleId] = true;
            this.changeCycleId(cId, cycle.links[0].cycleId);
            this.cycleCount[cId] = -1;
          }
          else {
            this.cycleCount[cID] += (cycleCount - 1);
            cycleMulti[cId] = true;
            this.changeCycleId(cycle.links[0].cycleId, cId);
            this.cycleCount[cycle.links[0].cycleId] = -1;
          }
        }
        else if ((cycle.links[0].cycleId == cId)) {
          if (cycle.links[0].cycleId == cId) {
            cycleCount += this.cycleBack(cycle.links[0]);
          }
          cycleCount += this.cycleBack(cycle);
          this.cycleCount[cId] += cycleCount;
        }
      }
      check = true;
    }

    if ((cycle.links[1] != null) && (cycle.links[1] != cycle.cyp)) {
      
      if (cycle.links[1].testCycle == false) {
        cycle.links[1].cyp = cycle;
        this.cycleQ.unshift(cycle.links[1]);
      }
      else if (cycle.links[1].testCycle == true){
        if (cycle.links[1].cycling == false) {
          if (cycle.links[1].cycleId == cId) {
            cycleCount += this.cycleBack(cycle.links[1]);
            this.cycleCount[cId] += cycleCount;
            cycleCount += this.cycleBack(cycle);
            this.cycleCount[cId] += cycleCount;
          }
        }
        else if ((cycle.links[1].cycleId != cId) && (cycle.links[1].cycleId != -1)) {
          cycleCount += this.cycleBack(cycle);
          if (cycle.links[1].cycleId < cId) {
            this.cycleCount[cycle.links[1].cycleId] += (cycleCount - 1);
            this.cycleMulti[cycle.links[1].cycleId] = true;
            this.changeCycleId(cId, cycle.links[1].cycleId);
            this.cycleCount[cId] = -1;
          }
          else {
            this.cycleCount[cId] += (cycleCount - 1);
            this.cycleMulti[cId] = true;
            this.changeCycleId(cycle.links[1].cycleId, cId);
            this.cycleCount[cycle.links[1].cycleId] = -1;
          }
        }
        else if ((cycle.links[1].cycleId == cId)) {
          if (cycle.links[1].cycleId == cId) {
            cycleCount += this.cycleBack(cycle.links[1]);
          }
          cycleCount += this.cycleBack(cycle);
          this.cycleCount[cId] += cycleCount;
        }
      }
      check = true;
    }

    if ((cycle.links[2] != null) && (cycle.links[2] != cycle.cyp)) {
      
      if (cycle.links[2].testCycle == false) {
        cycle.links[2].cyp = cycle;
        this.cycleQ.unshift(cycle.links[2]);
      }
      else if (cycle.links[2].testCycle == true) {
        if (cycle.links[2].cycling == false) {
          if (cycle.links[2].cycleId == cId) {
            cycleCount += this.cycleBack(cycle.links[2]);
            this.cycleCount[cId] += cycleCount;
            cycleCount += this.cycleBack(cycle);
            this.cycleCount[cId] += cycleCount;
          }
        }
        else if ((cycle.links[2].cycleId != cId) && (cycle.links[2].cycleId != -1)) {
          cycleCount += this.cycleBack(cycle);
          if (cycle.links[2].cycleId < cId) {
            this.cycleCount[cycle.links[2].cycleId] += (cycleCount - 1);
            this.cycleMulti[cycle.links[2].cycleId] = true;
            this.changeCycleId(cId, cycle.links[2].cycleId);
            this.cycleCount[cId] = -1;
          }
          else {
            this.cycleCount[cId] += (cycleCount - 1);
            this.cycleMulti[cId] = true;
            this.changeCycleId(cycle.links[2].cycleId, cId);
            this.cycleCount[cycle.links[2].cycleId] = -1;
          }
        }
        else if ((cycle.links[2].cycleId == cId)) {
          if (cycle.links[2].cycleId == cId) {
            cycleCount += this.cycleBack(cycle.links[2]);
          }
          cycleCount += this.cycleBack(cycle);
          this.cycleCount[cId] += cycleCount;
        }
      }
      check = true;
    }

    if ((cycle.links[3] != null) && (cycle.links[3] != cycle.cyp)) {
      if (cycle.links[3].testCycle == false) {
        cycle.links[3].cyp = cycle;
        this.cycleQ.unshift(cycle.links[3]);
      }
      else if (cycle.links[3].testCycle == true){ 
        if (cycle.links[3].cycling == false) {
          if (cycle.links[3].cycleId == cId) {
            cycleCount += this.cycleBack(cycle.links[3]);
            this.cycleCount[cId] += cycleCount;
            cycleCount += this.cycleBack(cycle);
            this.cycleCount[cId] += cycleCount;
          }
        }
        else if ((cycle.links[3].cycleId != cId) && (cycle.links[3].cycleId != -1)) {
          cycleCount += this.cycleBack(cycle);
          if (cycle.links[3].cycleId < cId) {
            this.cycleCount[cycle.links[3].cycleId] += (cycleCount - 1);
            this.cycleMulti[cycle.links[3].cycleId] = true;
            this.changeCycleId(cId, cycle.links[3].cycleId);
            this.cycleCount[cId] = -1;
          }
          else {
            this.cycleCount[cId] += (cycleCount - 1);
            this.cycleMulti[cId] = true;
            this.changeCycleId(cycle.links[3].cycleId, cId);
            this.cycleCount[cycle.links[3].cycleId]  = -1;
          }
        }
        else if ((cycle.links[3].cycleId == cId)) {
          if (cycle.links[3].cycleId == cId) {
            cycleCount += this.cycleBack(cycle.links[3]);
          }
          cycleCount +  this.cycleBack(cycle);
          this.cycleCount[cId] += cycleCount;
        }
      }
      check = true;
    }
  }

  while (this.changeQ.size() != 0) {

    var tempBlock = this.changeQ.pop();

    if (tempBlock.cycling == false) {
      tempBlock.testCycle  = false;
      tempBlock.cyp = null;
      tempBlock.cycleId = -1;
    }
  }

  this.cycleIdentification++;

  this.cycleQ.clear();

  this.cycleClean();

  return(cycleCount);
}

Gameboard.prototype.cycleBack = function(cycle) {
  
  var check = false;
  var count = -1;

  var tempBlock = cycle;
  
  while(check == false) {
    
    tempBlock.cycling = true;
    count++;
  
    if (tempBlock.cyp != null) {
      tempBlock  = tempBlock.cyp;
      check = false;
      continue;
    }
    else {
      check = true;
      break;
    }
  }

  this.cyleBackQ.clear();

  return(count);
}


